package com.gitee.wsl.ext.bitcode

import com.gitee.wsl.ext.base.getBit

fun Byte.isBitSet(pos:Int):Boolean = getBit(pos) != 0

internal fun getByteIndex(i: Long) = (i / 8).toInt()
internal fun getBitIndex(i: Long) = (i % 8).toInt()

fun List<Byte>.isBitSet(index: Long): Boolean =
 if (index < 0) throw IndexOutOfBoundsException("index = $index")
 else runCatching {
  this[getByteIndex(index)].isBitSet(getBitIndex(index))
 }.getOrElse { false }

fun Short.isBitSet(pos: Int): Boolean = this.toByte().isBitSet(pos)

fun UShort.isBitSet(pos: Int): Boolean = this.toShort().isBitSet(pos)

fun UByte.isBitSet(pos: Int): Boolean = this.toByte().isBitSet(pos)


/** Check if [this] has all the bits set in [bits] set */
 infix fun Int.hasFlags(bits: Int): Boolean = (this and bits) == bits
 infix fun Int.hasBits(bits: Int): Boolean = (this and bits) == bits

/** Check if a specific bit at [index] is set */
 infix fun Int.hasBitSet(index: Int): Boolean = ((this ushr index) and 1) != 0

 infix fun Long.hasFlags(bits: Long): Boolean = (this and bits) == bits
 infix fun Long.hasBits(bits: Long): Boolean = (this and bits) == bits

/** Creates an integer with only bit [bit] set */
 fun bit(bit: Int): Int = 1 shl bit

/** Returns the integer [this] without the [bits] set */
 fun Int.unsetBits(bits: Int): Int = this and bits.inv()

/** Returns the integer [this] with the [bits] set */
 fun Int.setBits(bits: Int): Int = this or bits

/** Returns the integer [this] with the [bits] set or unset depending on the [set] parameter */
 fun Int.setBits(bits: Int, set: Boolean): Int = if (set) setBits(bits) else unsetBits(bits)
